package com.game.common;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kodgames.core.threadPool.OrderedThreadPoolExecutor;
import com.game.core.net.handler.AbstractMessageInitializer;
import com.game.core.net.handler.AbstractProtobufMessageHandler;
import com.game.core.net.handler.ActionAnnotation;
import com.game.core.net.handler.BaseMessageHandler;
import com.game.core.util.PackageScaner;
import com.game.message.generaor.ProtocolConfigAnnotation;
import com.game.message.protocol.ProtocolsConfig;

public class Project4MessageInitializer extends AbstractMessageInitializer
{
	private static Logger logger = LoggerFactory.getLogger(Project4MessageInitializer.class);

	private String actionPackageName;
	
	public Project4MessageInitializer(String actionPackageName )
	{
		setBeforeExecutor(new OrderedThreadPoolExecutor(8, 32, 60, TimeUnit.SECONDS, "Project4MessageInitilizer"));
		this.actionPackageName = actionPackageName;
	}

	public String getActionPackageName()
	{
		return actionPackageName;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	protected void initMessages() throws Exception
	{
		Field[] fields = ProtocolsConfig.class.getDeclaredFields();
		//设置协议ID和协议的对应关系
		try
		{
			for (Field field : fields)
			{
				int protocolID = field.getInt(null);
				String protocolName = field.getName();
				ProtocolConfigAnnotation protocolAnnotation = field.getAnnotation(ProtocolConfigAnnotation.class);
				if (protocolAnnotation != null)
					setMessageIDClass(protocolID, protocolAnnotation.protocolClass(), protocolAnnotation.needLogin());
				else if (protocolName.startsWith("P_"))
					logger.warn("Don't set corresponding protocol class for the protocol:{} in the PrococolDesc.xml", protocolName);
			}
		}
		catch (Exception e)
		{
			logger.error("Failed to register the protocol ID and protocol Class");
			throw e;
		}

		//设置Action与Service与Handler之间关系
		try
		{
			if (actionPackageName == null)
			{
				logger.warn("Please set action package name for Project4MessageInitializer");
				return;
			}
			
			List<Class> commonActionClasses = PackageScaner.getClasses("com.game.common.action", ".class", true);
            List<Class> actionClasses = PackageScaner.getClasses(actionPackageName, ".class", true);
            actionClasses.addAll(commonActionClasses);
			for (Class actionClass : actionClasses)
			{
				Annotation annotation = actionClass.getAnnotation(ActionAnnotation.class);
				if (annotation != null)
				{
					ActionAnnotation actionAnnotation = (ActionAnnotation) annotation;
					setHandler(actionAnnotation.messageClass(), actionAnnotation.serviceClass(), (BaseMessageHandler<?>) actionClass.newInstance());
				}
				else if (AbstractProtobufMessageHandler.class.isAssignableFrom(actionClass))
					logger.warn("Please add ActionAnnotation for the Action:{}", actionClass.getSimpleName());
			}
		}
		catch (Exception e)
		{
			logger.error("Failed to register service Class and action Class");
			throw e;
		}
	}
}
